﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ServiceModel;
using System.Windows.Forms;
using Castle.ActiveRecord;
using FileManager_Server.BusinessLogic.AutoMapper_Setting;
using FileManager_Server.BusinessLogic.WCF.Client_Update_Service;
using FileManager_Server.DataLayer.Castle_Model;
using FileManager_Server.ServiceModel.DataTransfer_Model;
using FileManager_Server.Utility;
using System.Linq;

namespace FileManager_Server.BusinessLogic.WCF.System_Setting_Service
{
    public class SystemService : ISystemService
    {
        private ServiceHostCollection _serviceHost = new ServiceHostCollection();
        private BackgroundWorker _backgroundWorker;
        private static ToolStripLabel _toolStripLabel;
        private static ListView _logListView;
        private static ListView _systemListView;
        private static ListView _userLogView;
        public ServiceHostCollection StartWcfService(ToolStripLabel toolStripLabel, ListView listView, ListView userListView,ListView userlogView)
        {
            _toolStripLabel = toolStripLabel;
            CacheGlobal.Add(GlobalString.System_Config_String.CacheToolTipControl, _toolStripLabel);
            _logListView = listView;
            CacheGlobal.Add(GlobalString.System_Config_String.CacheLogListViewControl, _logListView);
            _systemListView = userListView;
            CacheGlobal.Add(GlobalString.System_Config_String.CacheSystemlistViewControl, _systemListView);
            _userLogView = userlogView;
            CacheGlobal.Add(GlobalString.System_Config_String.CacheUserLoglistViewControl, _userLogView); 
            _serviceHost.FileManager_UserService = new ServiceHost(typeof(FileManager_UserService));
            _serviceHost.NotifyMessage_Service = new ServiceHost(typeof(NotifyMessage_Service));
            _serviceHost.FileTransfer_Service = new ServiceHost(typeof(FileTransfer_Service));
            _serviceHost.ClientUpdate_Service = new ServiceHost(typeof(Client_UpdateService));
            _backgroundWorker = new BackgroundWorker();
            _backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
            _backgroundWorker.DoWork += backgroundWorker_DoWork;
            if (_backgroundWorker.IsBusy)
                _backgroundWorker.CancelAsync();
            _backgroundWorker.RunWorkerAsync();
            return _serviceHost;
        }

        void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                if (_serviceHost.FileManager_UserService.State != CommunicationState.Opened)
                    _serviceHost.FileManager_UserService.Open();
                if (_serviceHost.NotifyMessage_Service.State != CommunicationState.Opened)
                    _serviceHost.NotifyMessage_Service.Open();
                if (_serviceHost.FileTransfer_Service.State != CommunicationState.Opened)
                    _serviceHost.FileTransfer_Service.Open();
                if (_serviceHost.ClientUpdate_Service.State != CommunicationState.Opened)
                    _serviceHost.ClientUpdate_Service.Open();
                _logListView.Invoke((EventHandler) delegate
                                                       {
                                                           var listItem = new ListViewItem("服务已经启动......");
                                                           listItem.SubItems.Add(new ListViewItem.ListViewSubItem { Text = DateTime.Now.ToString() });
                                                           _logListView.Items.Add(listItem);
                                                       });
                e.Result = true;
            }
            catch (Exception ex)
            {
                e.Result = ex.Message;
                LogLoader.Instance.Log.Info("StartWcfService has problem", ex);
            }
        }

        void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            
        }


        public void StopWcfService(ServiceHostCollection serviceHost)
        {
            if (serviceHost == null) return;
            if (serviceHost.FileManager_UserService.State == CommunicationState.Opened)
                serviceHost.FileManager_UserService.Close();
            if (serviceHost.NotifyMessage_Service.State == CommunicationState.Opened)
                serviceHost.NotifyMessage_Service.Close();
            if (serviceHost.FileTransfer_Service.State == CommunicationState.Opened)
                serviceHost.FileTransfer_Service.Close();

        }


        public void InitializeCastle()
        {
            var source = System.Configuration.ConfigurationManager.GetSection(GlobalString.System_Config_String.CastleConfigSectionName) as Castle.ActiveRecord.Framework.IConfigurationSource;
            Type[] types =
                {
                    typeof (DepartmentDbModel),
                    typeof (OtherActiveRecord<>),
                    typeof (EmplyeeDbModel),
                    typeof (FileDbModel),
                    typeof (FileDepartsizeDbModel),
                    typeof (FileLogDbModel),
                    typeof (FileManagerDbModel),
                    typeof (FileRoleDbModel),
                    typeof (RolegroupDbModel),
                    typeof (UserDbModel),
                    typeof (Company),
                    typeof (CompanyGroup),
                    typeof (CompanyGroupMember),
                    typeof (UserGroup),
                    typeof (UserGroupMember)
                };
            ActiveRecordStarter.Initialize(source, types);
            AutoMapperInitialize.InitializeAutoMapper();
            var publisherEventCollection = new Dictionary<UserLoginResult, IPublisherEvents>();
            CacheGlobal.Add(GlobalString.System_Config_String.CachePublisherCollection,publisherEventCollection);
        }


        public void Subscriber(UserLoginResult userLoginResult)
        {
            try
            {
                var callback = OperationContext.Current.GetCallbackChannel<IPublisherEvents>();
                var publisherEventCollection =
                    CacheGlobal.GetCache(GlobalString.System_Config_String.CachePublisherCollection) as
                    Dictionary<UserLoginResult, IPublisherEvents>;
                if(null != publisherEventCollection)
                {
                    var currentUser =
                        publisherEventCollection.FirstOrDefault(x => x.Key.LoginId.Equals(userLoginResult.LoginId));
                    try
                    {
                        currentUser.Value.UserRepeatLoginLogOff();
                        publisherEventCollection.Remove(currentUser.Key);
                    }
                    catch
                    {
                    }

                    publisherEventCollection.Add(userLoginResult,callback);
                    _systemListView =
    CacheGlobal.GetCache(GlobalString.System_Config_String.CacheSystemlistViewControl) as ListView;
                    if (null != _systemListView)
                        _systemListView.Invoke((EventHandler)delegate
                        {
                            var hasUser = _systemListView.Items.Find(userLoginResult.UserId, true);
                            if (hasUser.Count() <= 0)
                            {
                                var listItem = new ListViewItem(userLoginResult.PeopleName);
                                listItem.Name = userLoginResult.UserId;
                                listItem.SubItems.Add(new ListViewItem.ListViewSubItem { Text = DateTime.Now.ToString() });
                                _systemListView.Items.Add(listItem);
                            }
                        });
                    _toolStripLabel = CacheGlobal.GetCache(GlobalString.System_Config_String.CacheToolTipControl) as ToolStripLabel;
                    _userLogView =
                            CacheGlobal.GetCache(GlobalString.System_Config_String.CacheUserLoglistViewControl) as
                            ListView;
                    if (null != _toolStripLabel && !_toolStripLabel.IsDisposed && null != _userLogView)
                    {
                        var message = string.Format("用户 {0} 已登录!", userLoginResult.PeopleName);
                        _userLogView.Invoke((EventHandler)delegate
                        {
                            var listItem = new ListViewItem(message);
                            listItem.SubItems.Add(new ListViewItem.ListViewSubItem { Text = DateTime.Now.ToString() });
                            _userLogView.Items.Add(listItem);
                        });
                    }
                }
                else
                {
                    publisherEventCollection = new Dictionary<UserLoginResult, IPublisherEvents>();
                    CacheGlobal.Add(GlobalString.System_Config_String.CachePublisherCollection, publisherEventCollection);
                }
            }
            catch (Exception ex)
            {
                LogLoader.Instance.Log.Info("Subscriber has problem", ex);
            }
        }

        public void UnSubscriber(UserLoginResult userLoginResult)
        {
            try
            {
                var publisherEventCollection =
                    CacheGlobal.GetCache(GlobalString.System_Config_String.CachePublisherCollection) as
                    Dictionary<UserLoginResult, IPublisherEvents>;
                if (null != publisherEventCollection)
                {
                    var currentUser =
                        publisherEventCollection.FirstOrDefault(x => x.Key.LoginId.Equals(userLoginResult.LoginId)).Key;
                    if (null != currentUser)
                    {
                        publisherEventCollection.Remove(currentUser);
                        _systemListView =
                            CacheGlobal.GetCache(GlobalString.System_Config_String.CacheSystemlistViewControl) as
                            ListView;
                        if (null != _systemListView)
                            _systemListView.Invoke((EventHandler) delegate
                                                                      {
                                                                          var hasUser =
                                                                              _systemListView.Items.Find(
                                                                                  currentUser.UserId, true);
                                                                          if (hasUser.Count() >= 0)
                                                                              _systemListView.Items.Remove(hasUser[0]);
                                                                      });
                        _toolStripLabel =
                            CacheGlobal.GetCache(GlobalString.System_Config_String.CacheToolTipControl) as
                            ToolStripLabel;
                        _userLogView =
                            CacheGlobal.GetCache(GlobalString.System_Config_String.CacheUserLoglistViewControl) as
                            ListView;
                        if (null != _toolStripLabel && !_toolStripLabel.IsDisposed)
                        {
                            var message = string.Format("用户 {0} 已离线!", currentUser.PeopleName);
                            _userLogView.Invoke((EventHandler) delegate
                                                                   {

                                                                       var listItem = new ListViewItem(message);
                                                                       listItem.SubItems.Add(
                                                                           new ListViewItem.ListViewSubItem
                                                                               {Text = DateTime.Now.ToString()});
                                                                       _userLogView.Items.Add(listItem);
                                                                   });
                        }
                    }
                    else
                    {
                        publisherEventCollection = new Dictionary<UserLoginResult, IPublisherEvents>();
                        CacheGlobal.Add(GlobalString.System_Config_String.CachePublisherCollection,
                                        publisherEventCollection);
                    }
                }
            }
            catch (Exception ex)
            {
                LogLoader.Instance.Log.Info("UnSubscriber has problem", ex);
            }
        }


        public void NotifyMessage(string message)
        {
            try
            {
                var publisherEventCollection =
               CacheGlobal.GetCache(GlobalString.System_Config_String.CachePublisherCollection) as
               Dictionary<UserLoginResult, IPublisherEvents>;
                if (null != publisherEventCollection)
                {
                    foreach (var publisherEventse in publisherEventCollection)
                    {
                        publisherEventse.Value.NotifyFileMessage(message);
                    }
                }
                else
                {
                    publisherEventCollection = new Dictionary<UserLoginResult, IPublisherEvents>();
                    CacheGlobal.Add(GlobalString.System_Config_String.CachePublisherCollection, publisherEventCollection);
                }
            }
            catch (Exception ex)
            {
                LogLoader.Instance.Log.Info("NotifyMessage has problem", ex);
            }
        }

        public void UpdateClientService(string version)
        {
            try
            {
                var publisherEventCollection =
               CacheGlobal.GetCache(GlobalString.System_Config_String.CachePublisherCollection) as
               Dictionary<UserLoginResult, IPublisherEvents>;
                if (null != publisherEventCollection)
                {
                    foreach (var publisherEventse in publisherEventCollection)
                    {
                        publisherEventse.Value.UpdateClientService(version);
                    }
                }
                else
                {
                    publisherEventCollection = new Dictionary<UserLoginResult, IPublisherEvents>();
                    CacheGlobal.Add(GlobalString.System_Config_String.CachePublisherCollection, publisherEventCollection);
                }
            }
            catch (Exception ex)
            {
                LogLoader.Instance.Log.Info("UpdateClientService has problem", ex);
            }
        }

        public void UserLogOff()
        {
            try
            {
                var publisherEventCollection =
               CacheGlobal.GetCache(GlobalString.System_Config_String.CachePublisherCollection) as
               Dictionary<UserLoginResult, IPublisherEvents>;
                if (null != publisherEventCollection)
                {
                    foreach (var publisherEventse in publisherEventCollection)
                    {
                        publisherEventse.Value.UserLogOffMessage();
                    }
                }
                else
                {
                    publisherEventCollection = new Dictionary<UserLoginResult, IPublisherEvents>();
                    CacheGlobal.Add(GlobalString.System_Config_String.CachePublisherCollection, publisherEventCollection);
                }
            }
            catch (Exception ex)
            {
                LogLoader.Instance.Log.Info("UserLogOff has problem", ex);
            }
        }
    }
}